/*
 * Widget.cpp
 *
 *	Author: stravant
 *	Description:
 *		
 */

#include "Widget.h"
#include "WidgetRoot.h"
#include "../core/Include.h"
#include "../ui/Canvas.h"

namespace tbt {

Widget::Widget(): mActive(true),
				mVisible(true),
				mTransparent(true),
				mBounds(0,0,0,0),
				mRoot(0),
				mDesiredPosition(kPositionAny, kPositionAny),
				mDesiredSize(kSizeAny, kSizeAny) {
}

Widget::~Widget() {
}

Ref<WidgetRoot> Widget::getRoot() const {
	return mRoot;
}

void Widget::captureMouse() {
	mRoot->setMouseGrab(this);
}

void Widget::releaseMouse() {
	mRoot->setMouseGrab(nullptr);
}

void Widget::focusKeyboard() {
	mRoot->setKeyGrab(this);
}

void Widget::blurKeyboard() {
	mRoot->setKeyGrab(nullptr);
}

void Widget::performLayout() {
	onLayout();
	mBoundsValid = true;
}

void Widget::performPaint(const IRect& region, fx::Context* ctx) {
	onPaint(region, ctx);
}

bool Widget::contains(const IVec& pos) const {
	return mBounds.contains(pos);
}

Ref<Widget> Widget::findWidgetForPoint(const IVec& pos) const {
	//invisible widgets ignored
	if (!isVisible()) return nullptr;

	//children first, in reverse draw order
	for (auto it = mChildren.rbegin(); it != mChildren.rend(); ++it) {
		auto widget = (*it)->findWidgetForPoint(pos);
		if (widget)
			return widget;
	}

	//children did not catch it, try self.
	if (isActive() && contains(pos))
		return const_cast<Widget*>(this);

	//this did not catch it
	return nullptr;
}

void Widget::addChild(Ref<Widget> child) {
	mChildren.push_back(child);
	child->setRoot(mRoot);
}

void Widget::removeChild(Ref<Widget> child) {
	mChildren.remove(child);
	child->setRoot(nullptr);
}

void Widget::onPaint(const IRect& region, fx::Context* ctx) {
	for (auto it = mChildren.begin(); it != mChildren.end(); ++it)
		(*it)->performPaint(region, ctx);
}

void Widget::onLayout() {
	for (auto it = mChildren.begin(); it != mChildren.end(); ++it)
		(*it)->onLayout();
}

void Widget::setChildBounds(Ref<Widget> child, const IRect& bounds) {
	child->setBounds(bounds);
}

void Widget::setRoot(Ref<WidgetRoot> root) {
	mRoot = root.get();
	for (auto it = mChildren.begin(); it != mChildren.end(); ++it)
		(*it)->setRoot(root);
}


}


















